package com.gjy.disruptor.uuid.dec.netty;

import com.gjy.disruptor.uuid.dec.disruptor.UuidEventHandler;
import com.gjy.disruptor.uuid.dec.disruptor.UuidEventProducer;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;

/**
 * Netty请求处理器，处理HTTP请求并返回UUID。
 *
 * @author gjy
 * @version 1.0
 * @since 2025-10-11 09:14:53
 */
public class UuidRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private static final Logger logger = LoggerFactory.getLogger(UuidRequestHandler.class);

    private final UuidEventProducer producer;
    private final UuidEventHandler handler;

    public UuidRequestHandler(UuidEventProducer producer) {
        this.producer = producer;
        this.handler = producer.getEventHandler();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
        // 检查请求路径是否为 /uuid
        if (!request.uri().equals("/uuid")) {
            sendErrorResponse(ctx, HttpResponseStatus.NOT_FOUND);
            return;
        }

        // 检查请求方法是否为GET
        if (request.method() != HttpMethod.GET) {
            sendErrorResponse(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED);
            return;
        }

        try {
            // 1. 触发Disruptor生产一个UUID事件
            producer.produce();

            // 2. 从EventHandler的队列中获取UUID (这会阻塞直到有UUID生成)
            String uuid = handler.takeUuid();

            // 3. 构造HTTP响应
            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(uuid, StandardCharsets.UTF_8)
            );
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
            response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());

            // 4. 发送响应并关闭连接
            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);

        } catch (InterruptedException e) {
            logger.error("Interrupted while waiting for UUID", e);
            sendErrorResponse(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR);
            Thread.currentThread().interrupt(); // 保留中断状态
        } catch (Exception e) {
            logger.error("Error processing request", e);
            sendErrorResponse(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private void sendErrorResponse(ChannelHandlerContext ctx, HttpResponseStatus status) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                status,
                Unpooled.copiedBuffer("Failure: " + status + "\r\n", StandardCharsets.UTF_8));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");

        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("Exception in handler", cause);
        ctx.close();
    }

}
